package model.world.tile;

import java.util.List;
import java.util.UUID;

import model.entity.Entity;
import model.entity.unit.Player;
import model.entity.unit.Unit;
import model.inventory.Inventory;
import model.world.Chunk;

public abstract class Tile {
	protected long x, y;
	protected Tile[] neighbors;
	protected Entity occupyingEntity;
	protected List<Unit> presentUnits;
	protected int baseCollectionRate;
	protected Chunk parentChunk;
	protected Inventory resources;
	protected UUID GUID;
	protected ResourceType resourceType;
	
	public Tile(long x, long y, Tile[] neighbors, Entity occupyingEntity, List<Unit> presentUnits, ResourceType resourceType, int baseCollectionRate, Chunk parentChunk, UUID GUID){
		this.x = x;
		this.y = y;
		this.neighbors = neighbors;
		this.occupyingEntity = occupyingEntity;
		this.presentUnits = presentUnits;
		this.baseCollectionRate = baseCollectionRate;
		this.parentChunk = parentChunk;
		this.GUID = GUID;
		this.resourceType = resourceType;
		resources = new Inventory();
	}
	
	public long getX(){
		return x;
	}
	
	public long getY(){
		return y;
	}
	
	public boolean addOccupyingEntity(Entity entity){
		if(occupyingEntity != null)
			return false;
		occupyingEntity = entity;
		return true;
	}
	
	public Entity getOccupyingEntity(){
		return occupyingEntity;
	}
	
	public boolean removeOccupyingEntity(Entity entity){
		if(occupyingEntity == entity){
			occupyingEntity = null;
			return true;
		}else{
			return false;
		}
	}
	
	public boolean addPresentUnit(Unit unit){
		return presentUnits.add(unit);
	}
	
	public Unit getPresentUnit(int i){
		if(presentUnits.size() <= i)
			return null;
		return presentUnits.get(i);
	}
	
	public int getNumPresentUnits(){
		return presentUnits.size();
	}
	
	public boolean removePresentUnit(Unit unit){
		return presentUnits.remove(unit);
	}
	
	public Tile getNeighbor(TileDirection d){
		return neighbors[d.toInt()];
	}
	
	public void setNeighbor(Tile tile, TileDirection d){
		neighbors[d.toInt()] = tile;
	}
	
	public Chunk getParentChunk(){
		return parentChunk;
	}
	
	public void tick(){
		if(occupyingEntity != null){
			int collectionRate = this.occupyingEntity.getResourceCollectionRate(resourceType) * this.baseCollectionRate;
			occupyingEntity.giveInventory(resources.subInventory(collectionRate));
		}
		for(Unit u : presentUnits){
			if(!(u instanceof Player)){
				u.tick();
			}
		}
	}

	public ResourceType getResourceType() {
		return resourceType;
	}
}
